/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.pig4cloud.pigx.ruralLibrary.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.ruralLibrary.api.entity.BookDataTypeEntity;
import com.pig4cloud.pigx.ruralLibrary.api.entity.BookExposureEntity;
import com.pig4cloud.pigx.ruralLibrary.api.entity.RecommendManageEntity;
import com.pig4cloud.pigx.ruralLibrary.api.entity.ResourceEntity;
import com.pig4cloud.pigx.ruralLibrary.api.vo.ArticleCatalogVo;
import com.pig4cloud.pigx.ruralLibrary.api.vo.JournalSearchResultVo;
import com.pig4cloud.pigx.ruralLibrary.mapper.ResourceMapper;
import com.pig4cloud.pigx.ruralLibrary.service.RecommendManageService;
import com.pig4cloud.pigx.ruralLibrary.service.ResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 资源
 *
 * @author pig
 * @date 2023-10-31 14:34:33
 */
@Service
@Slf4j
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, ResourceEntity> implements ResourceService {

    @Autowired
    private BookDataTypeServiceImpl bookDataTypeService;
    @Value("${digitallibrary.httpIp}")
    private String httpIp;

    @Value("${digitallibrary.username}")
    private String username;

    @Value("${digitallibrary.password}")
    private String password;
    @Value("${digitallibrary.productId}")
    private String productId;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveAll() {
        try {
            String a;
            String b;
            String token = bookDataTypeService.selectToken(httpIp + "/auth/oauth2/token");
            ObjectMapper objectMapper = new ObjectMapper();
            BookExposureEntity bookExposureEntity = new BookExposureEntity();
            bookExposureEntity.setUsername(username);
            bookExposureEntity.setPassword(password);
            bookExposureEntity.setProductId(productId);
            String json = objectMapper.writeValueAsString(bookExposureEntity);
            String jsonString = bookDataTypeService.resourceType(token, httpIp + "/digitallibrary/bookExposure/getProductResources", json);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            JSONArray dataArray = jsonObject.getJSONArray("data");

            ResourceEntity byId = this.getById(0);
            if (byId.getStatus().equals("0")) {
                a = "0";
                b = "1";
            } else {
                a = "1";
                b = "0";
            }
            byId.setStatus(b);
            this.updateById(byId);
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject dataObject = dataArray.getJSONObject(i);
                ResourceEntity bookType = new ResourceEntity();
                String id = dataObject.getString("resourceId");
                bookType.setResourceId(Long.valueOf(id));
                if (dataObject.getString("dataTypeId") != null) {
                    String dataTypeId = dataObject.getString("dataTypeId");
                    bookType.setDataTypeId(Long.valueOf(dataTypeId));
                }
                if (dataObject.getString("bookTypeId") != null) {
                    String bookTypeId = dataObject.getString("bookTypeId");
                    bookType.setBookTypeId(Long.valueOf(bookTypeId));
                }
                if (dataObject.getString("author") != null) {
                    bookType.setAuthor(dataObject.getString("author"));
                }
                if (dataObject.getString("createTime") != null) {
                    String pattern = "yyyy-MM-dd HH:mm:ss";
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
                    String createTimeStr = dataObject.getString("createTime");
                    LocalDateTime createTime = LocalDateTime.parse(createTimeStr, formatter);
                    bookType.setCreateTime(createTime);
                }
                if (dataObject.getString("press") != null) {
                    bookType.setPress(dataObject.getString("press"));
                }
                if (dataObject.getString("briefIntroduction") != null) {
                    bookType.setBriefIntroduction(dataObject.getString("briefIntroduction"));
                }
                if (dataObject.getString("resourceName") != null) {
                    bookType.setResourceName(dataObject.getString("resourceName"));
                }
                bookType.setCover(dataObject.getString("coverPictureUrl"));
                bookType.setStatus(b);
                ResourceEntity existingEntity = this.getById(id);
                if (existingEntity != null) {
                    this.updateById(bookType);
                } else {
                    long pageView = 0;
                    bookType.setPageView(pageView);
                    bookType.setType(pageView);
                    this.save(bookType);
                }

            }
            LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(ResourceEntity::getStatus, a);
            this.remove(wrapper);
            return R.ok("同步成功");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void pageView(Long resourceId) {
        ResourceEntity existingEntity = this.getById(resourceId);
        Long pageView = existingEntity.getPageView();
        existingEntity.setPageView(pageView + 1);
        this.updateById(existingEntity);
    }

    @Override
    public R getProductResourcesDetails(String resourceId) {
        try {
            String token = bookDataTypeService.selectToken(httpIp + "/auth/oauth2/token");
            ObjectMapper objectMapper = new ObjectMapper();
            BookExposureEntity bookExposureEntity = new BookExposureEntity();
            bookExposureEntity.setUsername(username);
            bookExposureEntity.setPassword(password);
            bookExposureEntity.setProductId(productId);
            bookExposureEntity.setResourceId(resourceId);
            String json = objectMapper.writeValueAsString(bookExposureEntity);
            String jsonString = bookDataTypeService.resourceType(token, httpIp + "/digitallibrary/bookExposure/getProductResourcesDetails", json);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            ResourceEntity byId = this.getById(resourceId);
            Long pageView = byId.getPageView();
            byId.setPageView(pageView + 1);
            this.updateById(byId);
//            log.info("getProductResourcesDetails:{}",jsonObject);
//            log.info("byId:{}",byId);
//            log.info("resourceId:{}",resourceId);
//            log.info("json:{}",json);
//            log.info("jsonString:{}",jsonString);
//            log.info("httpIp:{}",httpIp);
//            log.info("token:{}",token);
//            log.info("username:{}",username);
//            log.info("password:{}",password);
//            log.info("productId:{}",productId);
            jsonObject.put("pageView", byId.getPageView());
            System.out.println(jsonObject);

            return R.ok(jsonObject);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public R search(String search) {
        List<Map> lists = new ArrayList<>();
        LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.like(ResourceEntity::getResourceName, search);
        wrapper.eq(ResourceEntity::getStatus, "0");
        List<ResourceEntity> list = this.list(wrapper);

        Map<Long, List<ResourceEntity>> groupedMap = list.stream()
                .collect(Collectors.groupingBy(ResourceEntity::getDataTypeId));

        for (BookDataTypeEntity bookDataTypeEntity : bookDataTypeService.list()) {
            Map map = new HashMap();
            List<ResourceEntity> dataTypeId1List = groupedMap.get(bookDataTypeEntity.getId());
            map.put("dataTypeId", bookDataTypeEntity.getId());
            map.put("dataType", bookDataTypeEntity.getDataType());
            map.put("resource", dataTypeId1List);
            lists.add(map);
        }

        return R.ok(lists);
    }

    @Override
    public R books(Long id) {
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.isNotNull(ResourceEntity::getBriefIntroduction);
        wrapper.orderByDesc(ResourceEntity::getType);
        wrapper.last("LIMIT 5");
        List<ResourceEntity> resourceEntities = this.list(wrapper);
        map.put("book", resourceEntities);

        wrapper.clear();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.orderByDesc(ResourceEntity::getPageView);
        wrapper.last("LIMIT 10");
        List<ResourceEntity> resourceEntitie = this.list(wrapper);
        map.put("bookTop", resourceEntitie);

        list.add(map);
        return R.ok(list);
    }

    @Override
    public R video(Long id) {
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.isNotNull(ResourceEntity::getBriefIntroduction);
        wrapper.orderByDesc(ResourceEntity::getType);
        wrapper.last("LIMIT 5");
        List<ResourceEntity> resourceEntities = this.list(wrapper);
        map.put("video", resourceEntities);

        wrapper.clear();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.orderByDesc(ResourceEntity::getPageView);
        wrapper.last("LIMIT 10");
        List<ResourceEntity> resourceEntitie = this.list(wrapper);
        map.put("videoTap", resourceEntitie);

        list.add(map);
        return R.ok(list);
    }


    @Override
    public R periodical(Long id) {
        LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.orderByDesc(ResourceEntity::getType);
        long totalCount = 28;

        int pageSize = 14;

        long totalPages = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;

        List<List<ResourceEntity>> lists = new ArrayList<>();
        for (int i = 1; i <= totalPages; i++) {
            // 分页查询
            List<ResourceEntity> pageList = this.page(new Page<>(i, pageSize), wrapper).getRecords();
            // 将当前页的数据放到子列表中
            List<List<ResourceEntity>> subLists = splitList(pageList, pageSize);
            // 将子列表加入到结果列表中
            lists.addAll(subLists);
        }
        return R.ok(lists);
    }

    @Override
    public R particularsBooks(String bookId) {
        List<ResourceEntity> list = new ArrayList<>();
        boolean containsSeparator = bookId.contains(",") || bookId.contains("，");
        if (containsSeparator) {
            String[] ids = bookId.split("[,，]");
            for (String id : ids) {
                ResourceEntity byId = this.getById(id);
                if (byId == null) {
                    byId = new ResourceEntity();
                    byId.setResourceName("查无此图书");
                }
                list.add(byId);
            }
        } else {
            ResourceEntity byId = this.getById(bookId);
            if (byId == null) {
                byId = new ResourceEntity();
                byId.setResourceName("查无此图书");
            }
            list.add(byId);
        }

        return R.ok(list);
    }



    @Override
    public R getJournalSearchResult(String searchKeywords) {
        try {
            String token = bookDataTypeService.selectToken(httpIp + "/auth/oauth2/token");
            ObjectMapper objectMapper = new ObjectMapper();
            JournalSearchResultVo journalSearchResultVo = new JournalSearchResultVo();
            journalSearchResultVo.setSearchKeywords(searchKeywords);
            journalSearchResultVo.setSort("2");
            journalSearchResultVo.setIdentifier("J");
            String json = objectMapper.writeValueAsString(journalSearchResultVo);
            String jsonString = bookDataTypeService.resourceType(token, httpIp + "/digitallibrary/journal/getJournalSearchResult", json);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            JSONObject dataObject = jsonObject.getJSONObject("data");
            JSONArray resultsArray = dataObject.getJSONArray("results");
            for (int i = 0; i < resultsArray.size(); i++) {
                JSONObject result = resultsArray.getJSONObject(i);
                String journalname = result.getString("journalname");
                if (journalname.equals(searchKeywords)){
                    return R.ok(result);
                }
            }
            log.info("jsonObject: " + jsonObject);
            return R.failed("找不到当前期刊资源");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R getArticleCatalog(ArticleCatalogVo articleCatalogVo) {
        try {
            String token = bookDataTypeService.selectToken(httpIp + "/auth/oauth2/token");
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(articleCatalogVo);
            String jsonString = bookDataTypeService.resourceType(token, httpIp + "/digitallibrary/journal/getArticleCatalog", json);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            return R.ok(jsonObject);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R getArticleDetail(String id) {
        try {
            String token = bookDataTypeService.selectToken(httpIp + "/auth/oauth2/token");
            String jsonString = bookDataTypeService.get(token, httpIp + "/digitallibrary/journal/getArticleDetail/" + id);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            return R.ok(jsonObject);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R audio(Long id) {
        List<Map> list = new ArrayList<>();
        Map map = new HashMap();
        LambdaQueryWrapper<ResourceEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ResourceEntity::getDataTypeId, id);
        wrapper.isNotNull(ResourceEntity::getBriefIntroduction);
        wrapper.orderByDesc(ResourceEntity::getType);
        wrapper.last("LIMIT 5");
        List<ResourceEntity> resourceEntities = this.list(wrapper);
        map.put("audio", resourceEntities);

        wrapper.clear();
        wrapper.eq(ResourceEntity::getDataTypeId, id);

        wrapper.last("LIMIT 10");
        List<ResourceEntity> resourceEntitie = this.list(wrapper);
        map.put("audioTop", resourceEntitie);

        list.add(map);
        return R.ok(list);
    }

    @Override
    public R pageList(Page page, LambdaQueryWrapper<ResourceEntity> wrapper) {

        Page<ResourceEntity> paged = this.page(page, wrapper);

        List<ResourceEntity> records = paged.getRecords();
        for (ResourceEntity record : records) {
            BookDataTypeEntity byId = bookDataTypeService.getById(record.getDataTypeId());
            record.setStatus(byId.getDataType());
        }
        return R.ok(paged);
    }

    private <T> List<List<T>> splitList(List<T> list, int pageSize) {
        List<List<T>> result = new ArrayList<>();
        int count = list.size() % pageSize == 0 ? list.size() / pageSize : list.size() / pageSize + 1;
        for (int i = 0; i < count; i++) {
            int start = i * pageSize;
            int end = Math.min((i + 1) * pageSize, list.size());
            result.add(list.subList(start, end));
        }
        return result;
    }
}
